{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(23291027, 6)\n",
      "(620918, 3)\n",
      "(8324819, 19)\n",
      "(8595453, 19)\n",
      "(8858710, 19)\n"
     ]
    }
   ],
   "source": [
    "user_data = pd.read_csv(\"./data_result/user_data.csv\")\n",
    "item_data = pd.read_csv(\"./data_result/item_data.csv\")\n",
    "data_train = pd.read_csv(\"./data_result/data_train.csv\")\n",
    "data_eval = pd.read_csv(\"./data_result/data_eval.csv\")\n",
    "data_test = pd.read_csv(\"./data_result/data_test.csv\")\n",
    "print(user_data.shape)\n",
    "print(item_data.shape)\n",
    "\n",
    "\n",
    "print(data_train.shape)\n",
    "print(data_eval.shape)\n",
    "print(data_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 划分数据集  predict_date:预测日期\n",
    "def split_x_y(data, predict_date):\n",
    "    end_date = \"2014-12-1\" + str(int(predict_date[-1])+1)\n",
    "    #在此时间段购买商品的标签\n",
    "    labels = user_data[(user_data[\"time\"] >= predict_date)&(user_data[\"time\"] < end_date)&(user_data[\"behavior_type\"] == 4)][[\"user_id\", \"item_id\"]].drop_duplicates()\n",
    "    labels[\"is_buy\"] = 1\n",
    "    data = pd.merge(data, labels, how=\"left\", on=[\"user_id\", \"item_id\"])\n",
    "    data[\"is_buy\"] = data[\"is_buy\"].fillna(0)\n",
    "    x_train = data.drop([\"user_id\", \"item_id\", \"item_category\", \"is_buy\"], axis=1)\n",
    "   \n",
    "    y_train = data[\"is_buy\"]\n",
    "    print(end_date)\n",
    "    return (x_train, y_train)     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2014-12-18\n",
      "2014-12-19\n",
      "(8324819, 16)\n",
      "(8595453, 16)\n"
     ]
    }
   ],
   "source": [
    "# 训练集\n",
    "(x_train,y_train) = split_x_y(data_train, \"2014-12-17\")\n",
    "# 验证集\n",
    "(x_eval,y_eval) = split_x_y(data_eval, \"2014-12-18\")\n",
    "# 测试集 data_test\n",
    "print(x_train.shape)\n",
    "print(x_eval.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import xgboost as xgb\n",
    "xgb_train = xgb.DMatrix(x_train,y_train)\n",
    "xgb_eval = xgb.DMatrix(x_eval,y_eval)\n",
    "xbg_test = xgb.DMatrix(data_test.drop([\"user_id\", \"item_id\", \"item_category\"], axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.0    8322828\n",
      "1.0       1991\n",
      "Name: is_buy, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(y_train.value_counts())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试模型最优迭代次数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "xgb_params = {\n",
    "    'objective': 'rank:pairwise', # 学习目标\n",
    "    'eval_metric': 'auc', # 评价指标\n",
    "    'gamma': 0.1, # 最小损失函数下降值\n",
    "    'min_child_weight': 1.1, # 子集观察值的最小权重和\n",
    "    'max_depth': 6, # 树的最大深度\n",
    "    'lambda': 10, # L2正则化项\n",
    "    'subsample': 0.7, # 树采样率\n",
    "    'colsample_bytree': 0.7, # 特征采样率\n",
    "    'eta': 0.01, # 学习率\n",
    "    'tree_method':'exact', # 算法类别\n",
    "    'seed':0\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0]\ttrain-auc:0.929708\tvalidate-auc:0.880568\n",
      "Multiple eval metrics have been passed: 'validate-auc' will be used for early stopping.\n",
      "\n",
      "Will train until validate-auc hasn't improved in 4 rounds.\n",
      "[1]\ttrain-auc:0.942824\tvalidate-auc:0.904791\n",
      "[2]\ttrain-auc:0.9452\tvalidate-auc:0.913905\n",
      "[3]\ttrain-auc:0.949815\tvalidate-auc:0.923705\n",
      "[4]\ttrain-auc:0.951467\tvalidate-auc:0.926913\n",
      "[5]\ttrain-auc:0.952179\tvalidate-auc:0.929498\n",
      "[6]\ttrain-auc:0.954761\tvalidate-auc:0.933936\n",
      "[7]\ttrain-auc:0.954478\tvalidate-auc:0.933783\n",
      "[8]\ttrain-auc:0.954214\tvalidate-auc:0.933972\n",
      "[9]\ttrain-auc:0.953595\tvalidate-auc:0.933187\n",
      "[10]\ttrain-auc:0.953706\tvalidate-auc:0.933217\n",
      "[11]\ttrain-auc:0.95412\tvalidate-auc:0.933703\n",
      "[12]\ttrain-auc:0.954506\tvalidate-auc:0.934537\n",
      "[13]\ttrain-auc:0.954576\tvalidate-auc:0.93462\n",
      "[14]\ttrain-auc:0.954781\tvalidate-auc:0.934661\n",
      "[15]\ttrain-auc:0.955229\tvalidate-auc:0.93625\n",
      "[16]\ttrain-auc:0.955446\tvalidate-auc:0.936721\n",
      "[17]\ttrain-auc:0.955209\tvalidate-auc:0.93648\n",
      "[18]\ttrain-auc:0.955764\tvalidate-auc:0.936686\n",
      "[19]\ttrain-auc:0.955996\tvalidate-auc:0.936846\n",
      "141.31799983978271\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "a=time.time()\n",
    "watchlist = [(xgb_train,'train'),(xgb_eval,'validate')]\n",
    "model_xgb = xgb.train(xgb_params,xgb_train,num_boost_round=20,evals=watchlist,early_stopping_rounds=4)\n",
    "#说明：设置early_stopping_rounds=10，当logloss在10轮迭代之内，都没有提升的话，就stop。\n",
    "#如果说eval_metric有很多个指标，那就以最后一个指标为准。\n",
    "print(time.time()-a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from xgboost import plot_importance\n",
    "plot_importance(model_xgb)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "19\n"
     ]
    }
   ],
   "source": [
    "best_iteration=model_xgb.best_iteration\n",
    "print(best_iteration)  #最佳迭代次数\n",
    "#model_xgb = xgb.train(params,xgb_train,num_boost_round=model_xgb.best_iteration)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.model_selection import KFold\n",
    "from xgboost import XGBClassifier,XGBRegressor\n",
    "from sklearn.metrics import mean_absolute_error, make_scorer\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mae_score(y_true, y_pred):\n",
    "    return mean_absolute_error(np.exp(y_true), np.exp(y_pred))\n",
    "mae_scorer = make_scorer(mae_score, greater_is_better=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## max_depth,min_child_weight最优参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "xgb_param_grid = {'max_depth': list(range(4,9))}#, 'min_child_weight': list((1,3,6))\n",
    "grid = GridSearchCV(XGBRegressor(eta=0.1, num_boost_round=10, colsample_bytree=0.5, subsample=0.5,min_child_weight=1)\n",
    "                    ,param_grid=xgb_param_grid, cv=3, scoring='r2')# scoring='r2' 决定系数（拟合优度）模型越好：r2→1,模型越差：r2→0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[13:49:28] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[13:49:29] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[13:58:05] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[13:58:05] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[14:06:39] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[14:06:39] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[14:15:00] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[14:15:00] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[14:25:09] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[14:25:09] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[14:35:19] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[14:35:19] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[14:45:04] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[14:45:04] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[14:56:51] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[14:56:51] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[15:08:34] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[15:08:34] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[15:20:06] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[15:20:06] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n",
      "[15:33:45] WARNING: C:/Jenkins/workspace/xgboost-win64_release_0.90/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.\n",
      "[15:33:45] WARNING: C:\\Jenkins\\workspace\\xgboost-win64_release_0.90\\src\\learner.cc:686: Tree method is automatically selected to be 'approx' for faster speed. To use old behavior (exact greedy algorithm on single machine), set tree_method to 'exact'.\n"
     ]
    }
   ],
   "source": [
    "grid.fit(x_train, y_train.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "grid.grid_scores_, grid.best_params_, grid.best_score_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调节 gamma去降低过拟合风险"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xgb_param_grid = {'gamma':[ 0.1 * i for i in range(0,5)]}\n",
    "grid = GridSearchCV(XGBRegressor(eta=0.1, num_boost_round=best_iteration, max_depth=8, min_child_weight=6,\n",
    "                                        colsample_bytree=0.5, subsample=0.5),\n",
    "                    param_grid=xgb_param_grid, cv=3, scoring='r2')\n",
    "grid.fit(train_x, train_y.values)\n",
    "grid.grid_scores_, grid.best_params_, grid.best_score_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调节样本采样方式 subsample 和 colsample_bytree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xgb_param_grid = {'subsample':[ 0.1 * i for i in range(6,9)],\n",
    "                      'colsample_bytree':[ 0.1 * i for i in range(6,9)]}\n",
    "\n",
    "\n",
    "grid = GridSearchCV(XGBRegressor(eta=0.1, gamma=0.2, num_boost_round=best_iteration, max_depth=8, min_child_weight=6),\n",
    "                    param_grid=xgb_param_grid, cv=3, scoring='r2')\n",
    "grid.fit(train_x, train_y.values)\n",
    "grid.grid_scores_, grid.best_params_, grid.best_score_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 减小学习率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xgb_param_grid = {'eta':[0.5,0.4,0.3,0.2,0.1,0.075,0.05,0.04,0.03]}\n",
    "grid = GridSearchCV(XGBRegressor(num_boost_round=best_iteration, gamma=0.2, max_depth=8, min_child_weight=6,\n",
    "                                        colsample_bytree=0.6, subsample=0.9),\n",
    "                    param_grid=xgb_param_grid, cv=3, scoring='r2')\n",
    "\n",
    "grid.fit(train_x, train_y.values)\n",
    "grid.grid_scores_, grid.best_params_, grid.best_score_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 选择树的个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xgb_param_grid = {'num_boost_round':[20,50,100,200,300,400,500]}\n",
    "grid = GridSearchCV(XGBRegressor(gamma=0.2, max_depth=8, min_child_weight=6,eta=0.07,\n",
    "                                        colsample_bytree=0.6, subsample=0.9),\n",
    "                    param_grid=xgb_param_grid, cv=3, scoring='r2')\n",
    "grid.fit(train_x, train_y.values)\n",
    "grid.grid_scores_, grid.best_params_, grid.best_score_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 最优模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_xgb = XGBRegressor(num_boost_round=best_iteration, eta=0.07, gamma=0.2, max_depth=8, min_child_weight=6,\n",
    "                                        colsample_bytree=0.6, subsample=0.9)\n",
    "cv = model_xgb.kfold(train_x, train_y, nfold=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import MinMaxScaler\n",
    "eval_data = user_data[user_data[\"time\"] < \"2014-12-18\"][[\"user_id\", \"item_id\", \"item_category\"]].drop_duplicates()\n",
    "print(len(eval_data))\n",
    "eval_data[\"pred\"] = model_xgb.predict(xgb.DMatrix(x_eval))\n",
    "eval_data[\"pred\"] = MinMaxScaler().fit_transform(eval_data[\"pred\"].values.reshape(-1, 1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "threshold = eval_data[[\"pred\"]].sort_values(by=\"pred\", ascending=False).iloc[550][0]\n",
    "y_pred = eval_data[\"pred\"].tolist()\n",
    "for i in range(len(y_pred)):\n",
    "    if y_pred[i] >= threshold:\n",
    "        y_pred[i] = 1\n",
    "    else:\n",
    "        y_pred[i] = 0\n",
    "y_eval = y_eval.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "from sklearn.metrics import f1_score\n",
    "from sklearn.metrics import confusion_matrix\n",
    "print(\"Validate set accuracy score: {:.4f}\".format(accuracy_score(y_pred, y_eval)))\n",
    "print(\"Validate set F1 score : {:.4f}\".format(f1_score(y_pred, y_eval)))\n",
    "confusion_matrix(y_pred, y_eval) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import MinMaxScaler\n",
    "item_list = item_data[\"item_id\"].unique().tolist()\n",
    "predict = data_test[[\"user_id\", \"item_id\"]]\n",
    "predict[\"label\"] = model_xgb.predict(xbg_test)\n",
    "predict[\"label\"] = MinMaxScaler().fit_transform(predict[\"label\"].values.reshape(-1, 1))\n",
    "predict = predict[predict[\"item_id\"].isin(item_list)].sort_values(by=\"label\", ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = predict.head(550)[[\"user_id\", \"item_id\"]].drop_duplicates()\n",
    "result.to_csv(\"submission.csv\", index=False)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
